#include "AbstractItem.h"
#include "Defines.h"



#include <QTimer>


// todo: all data type names to common defines.
namespace
{
QString ID_FIELD_NAME = "id";
QString NAME_FIELD_NAME = "name";
QString DESC_FIELD_NAME = "description";
}



AbstractItem::AbstractItem(const int &category, QObject *parent)
    : QObject(parent)
{
    d = new Data();
    d->category = category;

    AbstractItem* parentItem = dynamic_cast<AbstractItem*>(parent);
    if (parentItem) connect(this, SIGNAL(sigDirty()), parentItem, SIGNAL(sigDirty()));
}

AbstractItem* AbstractItem::rootItem()
{
    AbstractItem* parentItem = dynamic_cast<AbstractItem*>(parent());
    if (!parentItem) return this;

    return parentItem->rootItem();
}


void AbstractItem::setData(const int &data_type, const QVariant &data)
{
    switch (data_type)
    {
    case IdData:
        if (!parent())
        {
            setObjectName(d->name.toString());
        }
        else if (parent()->objectName().isEmpty())
        {
            setObjectName(d->name.toString());
        }
        else
        {
            setObjectName(QString("%1.%2").arg(parent()->objectName()).arg(d->name.toString()));
        }

        foreach (AbstractItem* item, items())
        {
            item->setData(IdData);
        }
        return;

    case NameData:
        if (d->name == data) return;
        d->name = data;
        setData(IdData);
        break;

    case DescData:
        if (d->desc == data) return;
        d->desc = data;
        break;

    case CategoryData:
        if (d->category == data) return;
        d->category = data;
        break;

    default:
        setCustomData(data_type, data);
        return;
    }

    emit sigDirty();
}



QVariant AbstractItem::data(const int &data_type) const
{
    switch (data_type)
    {
    case IdData: return objectName();
    case NameData: return d->name;
    case DescData: return d->desc;
    case CategoryData: return d->category;
    }

    return customData(data_type);
    //return QVariant();
}



int AbstractItem::itemCount() const
{
    return items().count();
}



QList<AbstractItem*> AbstractItem::items() const
{
    QList<AbstractItem*> ret;
    foreach (AbstractItem* item, findChildren<AbstractItem*>())
    {
        if (!item || item->parent() != this) continue;

        ret.append(item);
    }

    return ret;
}



AbstractItem* AbstractItem::itemAt(const int& index) const
{
    QList<AbstractItem*> list = items();

    if (list.isEmpty() ||
        index < 0 ||
        index >= list.count()) return 0;

    return list.at(index);
}



QString AbstractItem::fieldName(const int& data_type) const
{
    switch (data_type)
    {
    //case IdData:   return ID_FIELD_NAME;
    case NameData: return NAME_FIELD_NAME;
    case DescData: return DESC_FIELD_NAME;
    default: return QString::null;
    }
}



int AbstractItem::field(const QString& field_name) const
{
    //if (field_name == ID_FIELD_NAME)   return IdData;
    if (field_name == NAME_FIELD_NAME) return NameData;
    if (field_name == DESC_FIELD_NAME) return DescData;

    return UndefinedData;
}



int AbstractItem::category() const
{
    QVariant v = data(CategoryData);
    if (!v.isValid()) return UNDEFINED;

    bool ok = false;
    int ret = v.toInt(&ok);

    if (!ok) return UNDEFINED;

    return ret;
}



QString AbstractItem::name() const
{
    QVariant v = data(NameData);
    if (!v.isValid()) return QString::null;

    return v.toString();
}



QString AbstractItem::desc() const
{
    QVariant v = data(DescData);
    if (!v.isValid()) return QString::null;

    return v.toString();
}



